Author(s): Zongcheng Li
reviewer(s): Ying Ge, Hui Huang Date: 2025-11-21

1 Academic Citation

If you use this code in your work or research, we kindly request that you cite our publication:

Xiaofan Lu, et al. (2025). FigureYa: A Standardized Visualization Framework for Enhancing Biomedical Data Interpretation and Research Efficiency. iMetaMed. https://doi.org/10.1002/imm3.70005

2 需求描述 Requirement description

这幅连线图很有趣,比FigureYa174squareCross多了两层信息:点的大小和颜色。

This line diagram is interesting because it has two more layers of information than FigureYa174squareCross: the size and color of the dots.

From https://www.biorxiv.org/content/10.1101/2020.07.21.214387v1

Figure 2: CellChat analysis of the communications between skin cells during wound repair. (a) Hierarchical plot shows the inferred intercellular communication network for TGFb signaling. Left and right panels highlight the autocrine and paracrine signaling to fibroblast states and other non-fibroblast skin cell states, respectively. Solid and open circles represent source and target, respectively. Circle sizes are proportional to the number of cells in each cell group. Edge colors are consistent with the signaling source.

类似的图: similar plot:

From https://molecular-cancer.biomedcentral.com/articles/10.1186/s12943-019-1066-3

Fig. 2 m6A regulators are correlated with the activation and inhibition of cancer pathways. a Network diagram demonstrating the correlation between m6A regulators and cancer pathways. Red represents a positive correlation, and blue represents a negative correlation. The size of the nodes corresponds to the number of links.

3 应用场景 Application scenarios

任意两组、多组连线,同时用颜色大小展示节点的更多信息,用连线的颜色粗细展示关系的类别强弱等信息。

根据自己数据的生物学意义,来排列各个节点的顺序。或许能够出现特殊的模式,从而展示出有意义的生物学规律。

上下左右连线的方法可参考FigureYa174squareCross。

Connect any two or multiple groups with lines, while using color and size to display additional node information, and the color/thickness of the connecting lines to represent relationship categories and strengths.

Arrange the order of nodes based on the biological significance of your data. This may reveal unique patterns, thereby demonstrating meaningful biological insights.

For methods of connecting nodes (top, bottom, left, right), refer to FigureYa174squareCross

4 环境设置 Environment settings

source("install_dependencies.R")
## 开始安装R包...
## Starting R package installation...
## ===========================================
## 包已安装: ggplot2 
## Package already installed: ggplot2 
## 包已安装: scales 
## Package already installed: scales 
## 包已安装: dplyr 
## Package already installed: dplyr 
## 
## ===========================================
## 验证安装结果:
## Verifying installation results:
## ✓ ggplot2 已成功安装
## ✓ ggplot2 installed successfully
## ✓ scales 已成功安装
## ✓ scales installed successfully
## ✓ dplyr 已成功安装
## ✓ dplyr installed successfully
## 
## 所有包已成功安装!
## 
## All packages installed successfully!
## 您现在可以使用以下代码加载这些包:
## You can now load these packages with the following code:
## library(ggplot2)
## library(scales)  # 提供数据缩放和颜色调整功能 / Provides data scaling and color adjustment functions
## library(dplyr)   # 提供数据操作和管道操作符 %>% / Provides data manipulation and pipe operator %>%
## 安装完成!
## Installation completed!
source("crosslink.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("layout.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("transfromation.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("utils.R") # From R package crosslink, https://github.com/zzwch/crosslink
source("crossplot.R") # From R package crosslink, https://github.com/zzwch/crosslink

library(dplyr) # 数据处理 data processing
## 
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2) # 画图 plot graph
library(scales) # 缩放 scale
Sys.setenv(LANGUAGE = "en") #显示英文报错信息 # error messages are displayed in English
options(stringsAsFactors = FALSE) #禁止chr转成factor # It is forbidden to convert chr into factor

5 输入文件 Input files

图中每个点、每条线的外观设置有两种方式供你选择。理解之后就可以灵活运用了,例如有些外观用代码写,有些外观填写在输入文件里。

  • 方式一:在输入文件中填写外观,个性化地写成不同的值。
    • 优点:所见即所得,写什么样就画出什么样
    • 缺点:麻烦
  • 方式二:在输入文件中最少可以只写id和type两列,其余外观都可以在画图时通过设置参数来实现。
    • 优点:方便修改,能用代码就不去一个一个写,便于跟上游分析衔接。
    • 缺点:外观种类太多时,其实不如“方式一”方便

easy_input_nodes.csv,每个节点为一行。第一列是节点id,之后是其类别type、颜色color、大小size、透明度alpha和形状shape。例如一个节点代表一个基因;type列就写gene;颜色、大小、透明度和形状都可以代表基因的某一特征值,例如表达量等。

easy_input_edges.csv,每两个被连起来的节点为一行,前两列是两个节点的id,之后是颜色color、类型type、透明度alpha和粗细size,这些外观信息可以代表每两个节点之间关系的强度、类型等。

There are two ways to customize the appearance of each point and line in the figure. Once understood, you can apply them flexibly—for example, setting some appearances via code while specifying others in the input file.

  • Option 1: Define appearances in the input file with custom values Pros: WYSIWYG (What You See Is What You Get)—the output will match exactly what you write. Cons: More tedious to set up.

  • Option 2: Keep the input file minimal (only id and type columns required) and control appearances via plotting parameters Pros: Easier to modify; avoids manual editing for each element and integrates smoothly with upstream analysis. Cons: Less convenient than Option 1 when dealing with too many appearance variations.

  • Input File Formats:easy_input_nodes.csv.Each row represents a node. The first column is the node id, followed by its type, color, size, alpha (transparency), and shape.

Example: If a node represents a gene, set type as “gene.”Other columns (color, size, alpha, shape) can encode additional features (e.g., expression levels).

  • easy_input_edges.csvEach row connects two nodes. The first two columns are the linked node ids, followed by color, type, alpha, and size (thickness).These attributes can reflect relationship strength, type, etc.
# 载入节点信息
# Load node information
nodes <- read.csv("easy_input_nodes.csv", header = T)
head(nodes)
##      id type   color size alpha shape
## 1 Gene1 Gene #FEE08B    6   0.8     4
## 2 Gene2 Gene #E6F598   10   0.5    14
## 3 Gene3 Gene #3288BD    7   0.9    15
## 4 Gene4 Gene #E6F598    5   0.8     3
## 5 Gene5 Gene #9E0142    4   0.6    12
## 6 Gene6 Gene #ABDDA4   10   0.8     2
# 载入连线信息
# Load the connection information
edges <- read.csv("easy_input_edges.csv", header = T)
head(edges)
##   source target   color type alpha size
## 1  Gene5   Mir1 #E31A1C    3   0.5    3
## 2  Gene6   Mir6 #1F78B4    1   0.6    3
## 3  Gene1   Mir2 #E31A1C    5   1.0    1
## 4  Gene9   Mir5 #1F78B4    3   0.6    1
## 5  Gene5   Mir1 #33A02C    4   0.9    1
## 6  Gene1   Mir3 #A6CEE3    3   0.7    1

6 开始画图 Start drawing the graph

6.1 方式一:所有外观都由输入文件决定 Method 1: All appearances are determined by the input file

# 写入想画的type
# Write the type you want to draw
columns <- list(# 如果你只有两个type(或者只想画两列),就在list里写两行。# If you only have two types (or just want to draw two columns), write two lines in the list
  Gene = nodes$id[nodes$type == "Gene"],
  Drug = nodes$id[nodes$type == "Drug"],
  Target = nodes$id[nodes$type == "Tar"], 
  Pathway = nodes$id[nodes$type == "Path"]
)

columnCross2(edges, nodes, columns,
             height = 1, flank_mult = rep(0.1, length(columns)), segment_shrink = 0.1,
             linetype = "type", line_alpha = "alpha", line_color = "color", line_size = "size",
             pt_shape = "shape", pt_alpha = "alpha", 
             pt_color = "color", # 外圈颜色 # Outer ring color
             pt_fill = "color", # 填充颜色 # Fill color
             pt_size = "size", pt_stroke = 1)
## Warning: Using `size` aesthetic for lines was deprecated in ggplot2 3.4.0.
## ℹ Please use `linewidth` instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.

ggsave(filename = "crosslink_file.pdf", width = 8, height = 5)

6.2 方式二:画图时设置外观参数 Method 2: Set the appearance parameters when drawing

# 写入想画的type
# 如果你只有两个type(或者只想画两列),就在list里写两行。
# Write the type you want to draw
# If you only have two types (or just want to draw two columns), write two lines in the list.
columns <- list(
  Gene = nodes$id[nodes$type == "Gene"],
  Drug = nodes$id[nodes$type == "Drug"],
  Target = nodes$id[nodes$type == "Tar"], 
  Pathway = nodes$id[nodes$type == "Path"]
)

# 以连线类型和节点形状为例,说明定义外观的两种方式,定义其他外观的方法类似
# Take the line type and node shape as an example to illustrate the two ways to define appearances, and the methods for defining other appearances are similar
columnCross2(edges, nodes, columns,
             height = 1, flank_mult = rep(0.1, length(columns)), segment_shrink = 0.1,
             
             linetype = 1, # 默认值,所有连线都画成直线 # By default, all lines are drawn as straight lines
             line_alpha = "alpha", line_color = "color", line_size = "size" ,
             
             #pt_shape = 21, # 统一画成实心圆 # Draw a solid circle in unison
             # 或者Drug画成空心圆,其余画成实心圆 # Or the Drug is drawn as a hollow circle, and the rest is drawn as a solid circle
             pt_shape = c(rep(16, length(columns$Gene)), rep(1, length(columns$Drug)), rep(16, (length(columns$Target) + length(columns$Pathway)))), 
             
             pt_alpha = .8, # 统一设置透明度 # Set transparency uniformly
             pt_color = "color", pt_fill = "color", pt_size = "size", 
             pt_stroke = 3) # 让空心圆的边粗一些 # Make the edges of the hollow circle thicker

ggsave(filename = "crosslink_par.pdf", width = 8, height = 5)

7 再来一个例子 One more example

如果某类节点太多,可以排成多列,就像需求描述的第二个例子那样。

If there are too many nodes of a certain type, you can arrange them into multiple columns, as in the second example of the requirements description.

7.1 输入文件 Input file

# 载入节点信息
# Load node information
nodes <- read.csv("easy_input2_nodes.csv", header = T)
head(nodes)
##   id type     color size alpha shape
## 1 P1    P firebrick    7   0.8    15
## 2 P2    P firebrick    4   0.9    15
## 3 P3    P firebrick    8   0.8    15
## 4 P4    P firebrick    9   0.6    15
## 5 P5    P firebrick   10   0.7    15
## 6 P6    P firebrick    4   0.9    15
# 载入连线信息
# Load connection information
edges <- read.csv("easy_input2_edges.csv", header = T)
head(edges)
##   source target color
## 1    P15  RBP20   red
## 2    P10  RBP17   red
## 3    P17   RBP4   red
## 4     P2  RBP14   red
## 5    P14   RBP4   red
## 6     P5   RBP5   red

7.2 开始画图 Start drawing the graph

# 这里把P和N都拆成两列,当然你也可以拆成更多列
# Split both P and N into two columns, but you can also split them into more columns
columns <- list(
  P1 = nodes$id[nodes$type == "P"][1:15],
  P2 = nodes$id[nodes$type == "P"][16:30],
  RBP = nodes$id[nodes$type == "RBP"],
  N1 = nodes$id[nodes$type == "N"][1:15], 
  N2 = nodes$id[nodes$type == "N"][16:30]
)
seq_len(length(columns))
## [1] 1 2 3 4 5
# 以连线类型和节点形状为例,说明定义外观的两种方式,定义其他外观的方法类似
# Take the line type and node shape as an example to illustrate the two ways to define appearances, and the methods for defining other appearances are similar
columnCross2(edges, nodes, columns,
             height = 1, 
             
             # 默认值是1,2,3,4,5,每列之间是等距的
             # 我们想让两边的两列距离近些,就这样改
             # The default values are 1, 2, 3, 4, 5, and each column is equidistant
             # We want to make the two columns on both sides closer, so change it like this
             column_x = c(1, 1.5, 3, 4.5, 5), 
             
             # 默认值都是0.1
             # 我们想让中间RBP那列短一些,就这样改
             # The default value is 0.1
             # We want to make the middle RBP column shorter, so change it like this
             flank_mult = c(0.1, 0.1, 0.15, 0.1, 0.1), 
             
             segment_shrink = 0,
             line_alpha = .2, line_size = 1, line_color = "color",
             pt_shape = "shape",  pt_alpha = "alpha", pt_color = "color", pt_fill = "color", pt_size = "size", pt_stroke = 1)

ggsave(filename = "crosslink_multiCol.pdf", width = 6, height = 8)

8 后期处理 Post-processing

输出的pdf文件是矢量图,可以用矢量图编辑器打开(例如Illustrator)调整图形、文字。

9 附 Attached

9.1 pt_shape的可选参数及其对应的形状 Optional parameters for pt_shape and their corresponding shapes

The output pdf file is a vector image, which can be opened with a vector editor (e.g. Illustrator) to adjust graphics, text.

9.2 示例一的输入数据生成过程 Example 1 of the input data generation process

# 节点的颜色
# The color of the node
node_colors <- RColorBrewer::brewer.pal(11, "Spectral")
# 连线的颜色
# The color of the wire
edge_colors <- RColorBrewer::brewer.pal(12, "Paired")

# nodes
nodes <- data.frame(
  id = c(paste0("Gene", 1:10), paste0("Meth", 1:10),
         paste0("Mir", 1:6), paste0("Drug", 1:8),
         paste0("Tar", 1:8), paste0("Path", 1:6)),
  type = c(rep("Gene", 10), rep("Meth", 10),
           rep("Mir", 6), rep("Drug", 8),
           rep("Tar", 8), rep("Path", 6)),
  color = sample(node_colors, 48, replace = T),
  size = sample(3:10, 48, replace = T),
  alpha = sample((5:10)/10, 48, replace = T),
  shape = sample(1:20, 48, replace = T)
)
write.csv(nodes, "easy_input_nodes.csv", quote = F, row.names = F)

# edges
edges <- data.frame(rbind(
  # gene vs mir
  data.frame(
    source = sample(nodes$id[nodes$type == "Gene"],
                    replace = T, 30),
    target = sample(nodes$id[nodes$type == "Mir"],
                    replace = T, 30)),
  # gene vs drug
  data.frame(
    source = sample(nodes$id[nodes$type == "Gene"],
                    replace = T, 100),
    target = sample(nodes$id[nodes$type == "Drug"],
                    replace = T, 100)),
  # meth vs drug
  data.frame(
    source = sample(nodes$id[nodes$type == "Meth"],
                    replace = T, 100),
    target = sample(nodes$id[nodes$type == "Drug"],
                    replace = T, 100)),
  # mir vs drug
  data.frame(
    source = sample(nodes$id[nodes$type == "Mir"],
                    replace = T, 20),
    target = sample(nodes$id[nodes$type == "Drug"],
                    replace = T, 20)),
  
  # drug vs target
  data.frame(
    source = nodes$id[nodes$type == "Drug"],
    target = nodes$id[nodes$type == "Tar"]),
  # target vs path
  data.frame(
    source = sample(nodes$id[nodes$type == "Tar"],
                    replace = T, 15),
    target = sample(nodes$id[nodes$type == "Path"],
                    replace = T, 15))
),
color = sample(edge_colors, 273, replace = T),
type = sample(1:5, 273, replace = T),
alpha = sample((5:10)/10, 273, replace = T),
size = sample(1:3, 273, replace = T))
write.csv(edges, "easy_input_edges.csv", quote = F, row.names = F)

9.3 示例二的输入数据的生成过程 Example 2 of the input data generation process

# 节点的颜色
# The color of the node
node_colors <- RColorBrewer::brewer.pal(11, "Spectral")
# 连线的颜色
# The color of the wire
edge_colors <- RColorBrewer::brewer.pal(12, "Paired")

# nodes
nodes <- data.frame(
  id = c(paste0("P", 1:30),
         paste0("RBP", 1:20),
         paste0("N", 1:30)),
  type = c(rep("P", 30),
           rep("RBP", 20),
           rep("N", 30)),
  color = c(rep("firebrick",30), sample(node_colors, 20,replace = T), rep("dodgerblue", 30)),
  size = sample(3:10, 80, replace = T),
  alpha = sample((5:10)/10, 80, replace = T),
  shape = c(rep(15,30), rep(16, 20), rep(15, 30))
)
write.csv(nodes, "easy_input2_nodes.csv", quote = F, row.names = F)

# edges
edges <- data.frame(rbind(
  # Positive pathway vs RBP
  data.frame(
    source = sample(nodes$id[nodes$type == "P"],
                    replace = T, 100),
    target = sample(nodes$id[nodes$type == "RBP"],
                    replace = T, 100)),
  # Negative pathway vs RBP
  data.frame(
    source = sample(nodes$id[nodes$type == "N"],
                    replace = T, 100),
    target = sample(nodes$id[nodes$type == "RBP"],
                    replace = T, 100))
),
color = c(rep("red", 100), rep("cornflowerblue", 100)))
write.csv(edges, "easy_input2_edges.csv", quote = F, row.names = F)

10 Session Info

sessionInfo()
## R version 4.5.2 (2025-10-31)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.3 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.26.so;  LAPACK version 3.12.0
## 
## locale:
##  [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
##  [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
##  [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
## [10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   
## 
## time zone: UTC
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] scales_1.4.0  ggplot2_4.0.1 dplyr_1.1.4  
## 
## loaded via a namespace (and not attached):
##  [1] crayon_1.5.3       vctrs_0.6.5        cli_3.6.5          knitr_1.50        
##  [5] rlang_1.1.6        xfun_0.54          generics_0.1.4     textshaping_1.0.4 
##  [9] S7_0.2.1           jsonlite_2.0.0     labeling_0.4.3     glue_1.8.0        
## [13] htmltools_0.5.8.1  ragg_1.5.0         sass_0.4.10        rmarkdown_2.30    
## [17] grid_4.5.2         evaluate_1.0.5     jquerylib_0.1.4    tibble_3.3.0      
## [21] fastmap_1.2.0      yaml_2.3.10        lifecycle_1.0.4    compiler_4.5.2    
## [25] RColorBrewer_1.1-3 pkgconfig_2.0.3    systemfonts_1.3.1  farver_2.1.2      
## [29] digest_0.6.39      R6_2.6.1           tidyselect_1.2.1   pillar_1.11.1     
## [33] magrittr_2.0.4     bslib_0.9.0        withr_3.0.2        tools_4.5.2       
## [37] gtable_0.3.6       cachem_1.1.0